/*******************************************************************************
* C语言程序入口
* 蒋晓岗<kerndev@foxmail.com>
*******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include "arm.h"
#include "intc.h"

typedef struct
{
	uint32_t TCFG0;
	uint32_t TCFG1;
	uint32_t TCON;
	uint32_t TCNTB0;
	uint32_t TCMPB0;
	uint32_t TCNTO0;
	uint32_t TCNTB1;
	uint32_t TCMPB1;
	uint32_t TCNTO1;
	uint32_t TCNTB2;
	uint32_t TCMPB2;
	uint32_t TCNTO2;
	uint32_t TCNTB3;
	uint32_t TCMPB3;
	uint32_t TCNTO3;
	uint32_t TCNTB4;
	uint32_t TCNTO4;
}TIMER_MMIO;

#define TIMER ((TIMER_MMIO*)0x51000000)

void swi_handler(void)
{
	int sp=0;
	printf("SWI: SP=%08x!\n", &sp);
}

void irq_handler(void)
{
	int sp=0;
	static int cnt=0;
	printf("IRQ: SP=%08x, CNT=%d\n", &sp, cnt++);
}

void print_vector(int *base)
{
	static const char rom[2048]={"rom"};
	printf("vector at %08x\n", base);
	printf("RST: %08x\n", base[0]);
	printf("UND: %08x\n", base[1]);
	printf("SWI: %08x\n", base[2]);
	printf("PRF: %08x\n", base[3]);
	printf("ABT: %08x\n", base[4]);
	printf("IRQ: %08x\n", base[5]);
	printf("FIQ: %08x\n", base[6]);	
	printf("%s\n", rom);
}

void setup_timer(void)
{
	intc_init();
	intc_set_handler(IRQ_TIMER4, irq_handler);
	intc_enable_irq(IRQ_TIMER4);
	arm_enable_irq();
	
	printf("TIMER->TCON=%x\n", TIMER->TCON);
	TIMER->TCFG0 = 0xffff;
	TIMER->TCNTB4 = 0xffff;
	TIMER->TCON = 7 << 20;
}

void loop(void)
{
	int sum=0;
	while(1)
	{
		for(int i=0; i<100000000; i++);
		printf("loop: %d\n", sum++);
	}
}

int main(void)
{
	int sp=0;
	printf("\n++++\nHello MSP=%08x!\n", &sp);
	arm_call_swi();
	arm_call_swi();
	arm_call_swi();
	print_vector((int*)0);
	setup_timer();
	printf("----\n");
	loop();
}
